#include "pincfg.h"
#include "systask.h"
#include "ff.h"
#include "NuMicro.h"
#include "usbh_lib.h"
#include "diskio.h"
#include "os_obj.h"
#include "common.h"
#include "bsp_api.h"

struct {
	volatile FRESULT fst;
	DIR dir;                /* Directory object */
	FIL usb_fil;
	uint32_t rev[4];
	FATFS  UsbFatFs;
	uu32 tick_start;
	uu32 tick_used;
} usb_fs = {0};

void pdf_author_demo(void);

/*****************************************************************************//*!
*
* @brief   led control.
*     
* @param   none
*
* @return  none
*
* @ Pass/ Fail criteria: none
*****************************************************************************/
void usb_task(void const *argument)
{
    char        *ptr, *ptr2;
    long        p1, p2, p3;
    BYTE        *buf;
    TCHAR       usb_path[] = { '3', ':', 0 };    /* USB drive started from 3 */
    FRESULT     res;
	

    UINT s1, s2, cnt, sector_no;
    static const BYTE ft[] = {0, 12, 16, 32};
    DWORD ofs = 0, sect = 0;
	
	char link_st = 0, tst_st = 0, rd_tst = 0;
	UINT FsResdLen;
	int link_time_cnt = 0;

	osDelay(100);
	
    /* HSUSB_VBUS_EN (USB 2.0 VBUS power enable pin) multi-function pin - PB.10   */
    //SYS->GPB_MFPH = (SYS->GPB_MFPH & ~SYS_GPB_MFPH_PB10MFP_Msk) | SYS_GPB_MFPH_PB10MFP_HSUSB_VBUS_EN;
    /* HSUSB_VBUS_ST (USB 2.0 over-current detect pin) multi-function pin - PB.11 */
    //SYS->GPC_MFPH = (SYS->GPC_MFPH & ~SYS_GPC_MFPH_PC14MFP_Msk) | SYS_GPC_MFPH_PC14MFP_HSUSB_VBUS_ST;
	
	// 不使用VBUS_ST时，应将usbh_core_init函数中的VBUS_ST极性设为高有效
	// 已测试，杂牌U盘不识别。惠普U 盘反复插拔正常，金士顿读正常，写失败。原因未知。
	// 测试时使用外5V供电
	// 惠普U盘写入速度 5MB/S
    usbh_core_init();
    usbh_umas_init();
    usbh_pooling_hubs();

	
    f_chdrive(usb_path);		/* set default path  */
    usbh_memory_used();			/* print out UsbHostLib memory usage information   */
			
	set_u32(usb_fs.rev, 0xEFEFEFEF, 4);		
	
    while(1)
    {
        usbh_pooling_hubs();
		
		if (usbh_umas_disk_status(3) == UMAS_OK)
		{
			link_time_cnt ++;
			if(link_time_cnt > 1000)
			{
				link_st = 1;
			}
		}
		else
		{
			link_st = 0;
			rd_tst = 0;
			tst_st = 0;
			link_time_cnt = 0;
		}
		
		if(link_st)
		{
			char f_op = 0;
			int wrcnt = 1000;
			void *wbuff, *rbuff;
			
			tx_mutex_get(os_obj.mid_file, INT32_MAX);
			
			while(!tst_st)
			{
				//usb_fs.fst = f_mount(&usb_fs.UsbFatFs, usb_path, 1);
				
				// path
				usb_fs.fst = f_chdrive(usb_path);          
				
				// read
				if(!rd_tst)
				{
					rbuff = calloc(128,8);
					usb_fs.fst = f_open(&usb_fs.usb_fil, "main.c", FA_READ | FA_WRITE);
					usb_fs.fst = f_read(&usb_fs.usb_fil, rbuff, 1000, &FsResdLen);
					if(usb_fs.fst == FR_OK)
					{
						file_dbg_puts(rbuff);
					}
					else
					{
						file_dbg_puts("read file fail \n");
					}
					usb_fs.fst = f_close(&usb_fs.usb_fil);
					free(rbuff);
					
					rd_tst = 1;
				}
				
				// write
				usb_fs.fst = f_open(&usb_fs.usb_fil, "m484evl.pdf", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
				
				if(usb_fs.fst != FR_OK) break;
				
				// pdf 文件流输出
				pdf_author_demo();

				f_op = 1;
				
				if(usb_fs.fst == FR_OK) {file_dbg_puts("usb file write sucess !\n");}
				else {file_dbg_print("usb file write fail ! res = %d\n", (int)usb_fs.fst);}
				
				usb_fs.fst = f_close(&usb_fs.usb_fil);
				
				if(usb_fs.fst != FR_OK)
					break;
				
				// write
				usb_fs.tick_start = app_tick_get();
				
				usb_fs.fst = f_open(&usb_fs.usb_fil, "BIGFIL.TXT", FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
				
				wbuff = malloc(4096);
				set_u8(wbuff,'*',4096);
				
				loop_n(256*10)
				{
					usb_fs.fst = f_write(&usb_fs.usb_fil, wbuff, 4096, &FsResdLen);
					if(usb_fs.fst != FR_OK)
					{
						file_dbg_print("write big file fail @ loop %d \n", index);
						break;
					}
				}
				
				usb_fs.tick_used = app_tick_get() - usb_fs.tick_start;
				
				free(wbuff);
				
				if(usb_fs.fst == FR_OK) {file_dbg_print("big file write sucess ! used time %d ms\n", usb_fs.tick_used);}
				else {file_dbg_print("usb file write fail ! res = %d\n", (int)usb_fs.fst);}
				
				usb_fs.fst = f_close(&usb_fs.usb_fil);
				
				
				
				tst_st = 1;
			}
			
			if(f_op)
			{
				//usb_fs.fst = f_close(&usb_fs.usb_fil);
				//usb_fs.fst = f_unmount(usb_path);
			}
			
			tx_mutex_put(os_obj.mid_file);
		}
		
        osDelay(1);
    }
}

int spdf_disk_out(uint8_t *buf, int len)
{
	UINT FsResdLen;
	
	usb_fs.fst = f_write(&usb_fs.usb_fil, buf, len, &FsResdLen);
	if(usb_fs.fst != FR_OK)
	{
		file_dbg_print("write pdf file fail \n");
	}
	return len;
}

